﻿using System;
using System.Data.Entity;
using System.Linq;
using System.Web.UI;
using GoFishWeb.Models;
using System.Text.RegularExpressions;

namespace GoFishWeb
{
    public partial class Join : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack) return;
            if (Request.UrlReferrer == null) Response.Redirect("~/Default.aspx");
            UpdateUI();
        }

        protected void btnStart_Click(object sender, EventArgs e)
        {
                using (var db = new GoFishContext())
                {
                    try
                    {
                        IsValidGameName();
                        CheckGameNameExisting();
                        var game = new GoFishGame(txtGameName.Text);
                        game.AddPlayer(User.Identity.Name);
                        db.Games.Add(game);

                        var record = db.PlayerRecords.FirstOrDefault(r => r.UserName.Equals(User.Identity.Name));
                        if (record != null)
                            record.Games.Add(game);

                        db.SaveChanges();
                        Response.Redirect("~/GamePlay.aspx?game=" + game.Id + "&type=start");
                    }
                    catch (Exception exception)
                    {
                        lblErrorMessage.Text = exception.Message;
                        lblErrorMessage.Visible = true;
                    }
                }
        }

        private void IsValidGameName()
        {
            var match = Regex.Match(txtGameName.Text, "^[0-9a-zA-Z]*$", RegexOptions.IgnoreCase).Success;
            if (!match)
                throw new ArgumentException(string.Format("{0} is not a valid game name.", txtGameName.Text));
        }

        private void CheckGameNameExisting()
        {
            using (var db = new GoFishContext())
            {
                var existing = db.Games.Any(x => x.Name == txtGameName.Text);
                if (existing)
                    throw new ArgumentException(string.Format("{0} already exists. Please use a different game name.", txtGameName.Text));
            }
        }

        protected void btnJoin_Click(object sender, EventArgs e)
        {        
            try
            {
                using (var db = new GoFishContext())
                {
                    var gameId = int.Parse(ListBox1.SelectedValue);
                    var game = db.Games.FirstOrDefault(g => g.Id == gameId);
                    if(game != null)
                        game.AddPlayer(User.Identity.Name);

                    var record = db.PlayerRecords.FirstOrDefault(r => r.UserName.Equals(User.Identity.Name));
                    if (record != null)
                    {
                        record.Games.Add(game);

                        db.Entry(record).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                }
                Response.Redirect("~/GamePlay.aspx?game=" + ListBox1.SelectedValue + "&type=join");
            }
            catch (FormatException)
            {
                lblErrorMessage.Visible = true;
                lblErrorMessage.Text = "Please select a game to join.";
            }

        }

        protected void btnRejoin_Click(object sender, EventArgs e)
        {
            try
            {
                using (var db = new GoFishContext())
                {
                    var gameId = int.Parse(RejoinListBox.SelectedValue);
                    var game = db.Games.FirstOrDefault(g => g.Id == gameId);
                    if (game != null)
                        game.AddPlayer(User.Identity.Name);

                    var record = db.PlayerRecords.FirstOrDefault(r => r.UserName.Equals(User.Identity.Name));
                    if (record != null)
                        record.Games.Add(game);
                    
                    db.SaveChanges();
                }
                Response.Redirect("~/GamePlay.aspx?game=" + RejoinListBox.SelectedValue + "&type=rejoin");
            }
            catch (FormatException)
            {
                lblErrorMessage.Visible = true;
                lblErrorMessage.Text = "Please select a game to rejoin.";
            }

        }

        protected void Timer1_Tick(object sender, EventArgs e)
        {
            UpdateUI();
        }

        private void UpdateUI()
        {
            using (var db = new GoFishContext())
            {
                ListBox1.DataTextField = "Name";
                ListBox1.DataValueField = "Id";
                ListBox1.DataSource = db.Games.Where(x => !x.IsGameStarted && !x.IsGameOver).ToList();
                ListBox1.DataBind();

                RejoinListBox.DataTextField = "Name";
                RejoinListBox.DataValueField = "Id";
                RejoinListBox.DataSource = db.Games.Where(x => x.IsGameStarted && !x.IsGameOver && x.Players.Select(p => p.Name).Contains(User.Identity.Name)).ToList();
                RejoinListBox.DataBind();
            }
        }
    }
}